#include "searchwindow.h"
#include "ylib.h"

#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
// #include <sys/stat.h>

#define MAX_BTN_COUNT   3
#define BTN_P_POS_Y     40
#define BTN_WIDTH       100
#define BTN_HEIGHT      100
#define BTN_N_POS_Y     (480 - BTN_P_POS_Y - BTN_HEIGHT)
#define BTN_PIXELS      18
#define BTN_POS_X       700
#define PTEXT_LINE_H    20
#define PTEXT_PAGE_LINE_COUNT   20
#define LIST_WIDTH      600
#define LIST_HEIGHT     (PTEXT_LINE_H * PTEXT_PAGE_LINE_COUNT)
#define LIST_POS_X      100
#define LIST_POS_Y      ((480 - LIST_HEIGHT) / 2)
#define BAR_WIDTH       600
#define BAR_HEIGHT      50
#define BAR_POS_X       ((800 - BAR_WIDTH) / 2)
#define BAR_POS_Y       ((480 - BAR_HEIGHT) / 2)

struct BDir bmpDir;

static bool isInit = false;
static int curr_pages = 0;
static Filename *curr_filename = NULL;
static GraphRect btns[MAX_BTN_COUNT];
static font *__fp = NULL;
static bitmap *__PtextMap = NULL;
static bitmap *__backMap = NULL;

static Filename *create_Filename(char *prefix, int prelen, char filename[]);
static void destroy_Filename(Filename *filename);
static inline void insert_bmpdir(Filename *filename)
{
    list_insert(&bmpDir.node, &filename->node);
    bmpDir.length++;    // 长度 +1
}

// 进度条
static void __draw_bar();

// 绘制按钮
static void __draw_btns();

// 绘制 路径显示列表
static void __draw_filename_list(int k);

// 初始化 检索界面
int init_searchwindow(char *dirname)
{
// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);
    // 初始化 文件路径头
    bmpDir.node.next = &bmpDir.node;
    bmpDir.node.prev = &bmpDir.node;
    bmpDir.length = 0;

    // 读取目录
    DIR *dir = opendir(dirname);
    if (dir == NULL){
        return -1;
    }

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);

    struct dirent *dirt = NULL;
    int len = strlen(dirname);
    char *ydirname = NULL;
    if (dirname[len-1] != '/'){
        ++len;
    }
    ydirname = (char*)malloc(len);
    strcpy(ydirname, dirname);
    ydirname[len-1] = '/';
    while (1){
        dirt = readdir(dir);    // 读取一项
        if (dirt == NULL) break;

        // 查找 bmp 图片文件
        char *p = strstr(dirt->d_name, ".bmp");
        if (p == NULL) continue;
        if (dirt->d_type == DT_REG && (strcmp(p, ".bmp") == 0)){
            Filename *filename = create_Filename(ydirname, len, dirt->d_name);
            if (filename == NULL){
                closedir(dir);
                return -1;
            }
            insert_bmpdir(filename);
        }
    }

    closedir(dir);
    free(ydirname);
    if (bmpDir.length != 0) curr_filename = list_entry(bmpDir.node.next, typeof(*curr_filename), node);

    // 打开文字
    __fp = fontLoad("../font/simfang.ttf");
    if (__fp == NULL){
        fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);
    }
    fontSetSize(__fp, BTN_PIXELS);

    // 文字显示列表
    __PtextMap = createBitmapWithInit(LIST_WIDTH, LIST_HEIGHT, 3, 0xffffff<<8);
    __backMap = createBitmapWithInit(LIST_WIDTH, LIST_HEIGHT, 3, 0xffffff<<8);

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);
}

// 绘制  检索界面
void draw_searchwindow()
{
    clear_lcd(0xffffff);// 清屏 白色
    if (!isInit){
        __draw_bar();
        isInit = true;
        clear_lcd(0xffffff);// 清屏 白色
    }

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);
    // 绘制按钮
    __draw_btns();

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);
    // 绘制 路径块
    __draw_filename_list(0);
// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);
}

// 检查是否在任意按钮
int check_btn_SW(int x, int y)
{
// fprintf(stderr, "-------------------------- check -----------------------\n");

    for (int i=0; i<MAX_BTN_COUNT; ++i){
        if ((btns[i].x <= x && btns[i].x+btns[i].width >= x) && (btns[i].y <= y && btns[i].y+btns[i].height >= y)){
            if (i == SWPrev && curr_pages>0){
                __draw_filename_list(-1);
            }else if (i == SWNext){

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);

                __draw_filename_list(1);
            }
            return i;
        }
    }
    return -1;
}

// 销毁检索界面
void destory_searchwindow()
{
    // 释放 链表
    list_node *phead = &(bmpDir.node),
              *p     = phead->next;
    list_node *t = NULL;
    Filename *fp = NULL;
    for (int i=0; i<bmpDir.length; ++i){
        fp = list_entry(p, typeof(*fp), node);
        t = p;
        p = p->next;
        // 从链表中剔除
        list_delete(t);
        // 释放资源
        destroy_Filename(fp);
    }

    // 释放字体 显示块
    fontUnload(__fp);
    destroyBitmap(__PtextMap);
    destroyBitmap(__backMap);
}

static Filename *create_Filename(char *prefix, int prelen, char filename[])
{
    
    // 变长数组 多余的空间给到 路径字符数组
    int32_t size = sizeof(Filename) + prelen + strlen(filename) + 1;// 1 是 '\0'
    Filename *fp = (Filename*)malloc(size);
    if (fp == NULL) return NULL;
// fprintf(stderr, "file:%s %d\n", __FILE__, __LINE__);
    sprintf(fp->filename, "%s%s", prefix, filename);
    // strcpy(fp->filename, filename);
    return fp;
}

static void destroy_Filename(Filename *filename)
{
    free(filename);
}

// 进度条
static void __draw_bar()
{
    // 绘制提示  “目录检索中”
    font *fp = fontLoad("../font/simfang.ttf");
    if (fp == NULL){
        fprintf(stderr, "%d\n", __LINE__);
        return ;
    }
    fontSetSize(fp, BTN_PIXELS);
    bitmap *bmap = createBitmapWithInit(100, PTEXT_LINE_H, 3, 0xffffff<<8);
    fontPrint(fp, bmap, 0 , 0, "目录检索中……", 0x0, 0);
    draw_graph(bmap->map, BAR_POS_X, BAR_POS_Y-30, bmap->width, bmap->height, bmap->byteperpixel, false);
    fontUnload(fp);
    destroyBitmap(bmap);

    // 绘制边框  边框应该要大于里边
    draw_rect(BAR_POS_X-1, BAR_POS_Y-1, BAR_WIDTH+2, BAR_HEIGHT+2, 0x0);

    // 绘制里面的条  延时3秒
    int delaytime = 3;
    int offset = BAR_WIDTH / (2 * delaytime);
    for (int i=0; i<2*delaytime; ++i){

        clear_rect(0x00ff00, BAR_POS_X + i*offset, BAR_POS_Y, offset, BAR_HEIGHT);
        // 暂停 500 毫秒
        for (int j=0; j<5; ++j){
            usleep(100000);
        }
    }

}

// 绘制按钮
static void __draw_btns()
{
    // 绘制 上一页 按钮
    btns[0] = create_Btn(BTN_POS_X, BTN_P_POS_Y, BTN_WIDTH, BTN_HEIGHT, __fp, BTN_PIXELS, 0xffffff, 0x0, "上一页");

    // 绘制 下一页 按钮
    btns[1] = create_Btn(BTN_POS_X, BTN_N_POS_Y, BTN_WIDTH, BTN_HEIGHT, __fp, BTN_PIXELS, 0xffffff, 0x0, "下一页");

    // 绘制 退出 按钮
    btns[2] = create_Btn(BTN_POS_X, (480/2)-(BTN_HEIGHT/2), BTN_WIDTH, BTN_HEIGHT, __fp, BTN_PIXELS, 0xffffff, 0x0, "退出");
}

// 绘制 路径显示列表
static void __draw_filename_list(int k)
{
    if (curr_filename == NULL) return ;
    list_node *p = &(curr_filename->node);
    list_node *phead = &(bmpDir.node);

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);
    // 倒退 上一页
    if (k == -1){
        for (int i=0; i<PTEXT_PAGE_LINE_COUNT && phead != p; ++i){
            p = p->prev;
        }
        if (curr_pages) curr_pages--;
    }else if (k == 1){// 前进 下一页
        for (int i=0; i<PTEXT_PAGE_LINE_COUNT && phead != p; ++i){
            p = p->next;
        }
        curr_pages++;
    }
    // 如果都移动到头  那就重新赋值
    if (p == phead) p = p->next;

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);

    // 重置原来的 文字显示块
    memcpy(__PtextMap->map, __backMap->map, __PtextMap->width*__PtextMap->height*__PtextMap->byteperpixel);

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);

    Filename *fp = NULL;
    for (int i=0; i<PTEXT_PAGE_LINE_COUNT && p!=phead; ++i){
        fp = list_entry(p, typeof(*fp), node);
        fontPrint(__fp, __PtextMap, 0, i*PTEXT_LINE_H, fp->filename, 0x0, 0);
        p = p->next;
    }

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);

    // 绘制 显示块的边框
    draw_rect(LIST_POS_X-1, LIST_POS_Y-1, LIST_WIDTH+2, LIST_HEIGHT+2, 0x0);

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);

    // 绘制 路径显示块
    draw_graph(__PtextMap->map, LIST_POS_X, LIST_POS_Y, __PtextMap->width, __PtextMap->height, __PtextMap->byteperpixel, false);

// fprintf(stderr, "file:%s %d\n",__FILE__ , __LINE__);

}